package org.rainbowinverted.charging.device.connect.ykc.server.handler;

import cn.hutool.core.util.HexUtil;
import org.rainbowinverted.charging.device.connect.ykc.server.message.in.YkcDeviceOtaIn;
import org.rainbowinverted.charging.device.connect.ykc.server.message.in.YkcMessageIn;
import org.rainbowinverted.charging.device.connect.ykc.server.message.out.YkcDeviceOtaOut;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

/**
 * 二维码处理器
 * @author hehuaiping
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class YkcDeviceOtaHandler extends YkcAbstractHandler<YkcDeviceOtaIn, YkcDeviceOtaOut> {
    @Override
    public void read(ChannelHandlerContext channel, YkcMessageIn message) {
        ByteBuf messageBody = message.getMessageBody();
        Long deviceNo = readDeviceNo(messageBody);
        // 0x00-成功
        // 0x01-编号错误
        // 0x02-程序与桩型号不符
        // 0x03-下载更新文件超时
        byte updateResult = messageBody.readByte();
        YkcDeviceOtaIn ykcDeviceQrcodeIn = new YkcDeviceOtaIn(deviceNo, updateResult == 0x00);
        log.info("ykcDeviceOtaIn: deviceNo: {} updateResult: {}", deviceNo, updateResult);
        complete(message.getFrameSerialNo(), ykcDeviceQrcodeIn);
    }

    @Override
    public void write(ByteBuf byteBuf, YkcDeviceOtaOut out) {
        writeDeviceNo(byteBuf, out.getDeviceNo());
        // 桩类型
        byteBuf.writeByte(out.getDeviceType());
        // 桩功率
        byteBuf.writeShort(out.getDevicePower());
        // ftp IP
        byteBuf.writeBytes(HexUtil.decodeHex(str2Hex(out.getUsername(), 32)));
        // ftp port
        byteBuf.writeShort(out.getFtpPort());
        // 用户名
        byteBuf.writeBytes(HexUtil.decodeHex(str2Hex(out.getUsername(), 32)));
        // 密码
        byteBuf.writeBytes(HexUtil.decodeHex(str2Hex(out.getPassword(), 32)));
        // 文件路径
        byteBuf.writeBytes(HexUtil.decodeHex(str2Hex(out.getFilePath(), 64)));
        // 执行控制
        byteBuf.writeByte(out.getExecuteControl());
        // 下载超时时间
        byteBuf.writeByte(out.getDownloadTimeOut());
        createCompletableFuture(out.getFrameSerialNo());
    }

    /**
     * 字符串转十六进制
     * @param str 字符串
     * @param length 长度
     * @return {@link String}
     */
    private String str2Hex(String str, Integer length) {
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        StringBuilder hex = new StringBuilder();
        for (byte b : bytes) {
            hex.append(String.format("%02x", b));
        }
        while (hex.length() < length) {
            hex.append("00");
        }
        return hex.toString();
    }
}
